/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Juego;

import Juego.Estrategia.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Flor
 */
public class Jugador {

    private String nombre;
    private Integer montoDisponible;
    private Jugador sigJugador;
    private List<Carta> lstCartas;
    private boolean dealer;
    private boolean activo;
    private Integer uApuesta;
    protected IEstrategia estrategia;
    private boolean prestamoActivo = false;
    private boolean sigueEnLaPartida = true;
    private boolean allIn = false;

    //GETTER AND SETTER
    public boolean isAllIn() {
        return allIn;
    }

    public void setAllIn(boolean allIn) {
        this.allIn = allIn;
    }

    public boolean isSigueEnLaPartida() {
        return sigueEnLaPartida;
    }

    public void setSigueEnLaPartida(boolean sigueEnLaMano) {
        this.sigueEnLaPartida = sigueEnLaMano;
    }

    public boolean isPrestamoActivo() {
        return prestamoActivo;
    }

    public void setPrestamoActivo(boolean prestamoActivo) {
        this.prestamoActivo = prestamoActivo;
    }

    public Integer getuApuesta() {
        return uApuesta;
    }

    public void setuApuesta(int uApuesta) {
        this.uApuesta = uApuesta;
    }

    public boolean isActivo() {

        return activo;
    }

    public void setActivo(boolean activo) {

        this.activo = activo;
    }

    public boolean isDealer() {
        return dealer;
    }

    public void setDealer(boolean dealer) {

        this.dealer = dealer;
    }

    public List<Carta> getLstCartas() {
        return lstCartas;
    }

    public void setLstCartas(List<Carta> lstCartas) {

        this.lstCartas = lstCartas;
    }

    public Integer getMontoDisponible() {

        return montoDisponible;
    }

    public void setMontoDisponible(int montoDisponible) {

        this.montoDisponible = montoDisponible;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {

        this.nombre = nombre;
    }

    public Jugador getSigJugador() {
        return sigJugador;
    }

    public void setSigJugador(Jugador sigJugador) {
        this.sigJugador = sigJugador;
    }

    public IEstrategia getEstrategia() {
        return estrategia;
    }

    public void setEstrategia(IEstrategia estrategia) {

        this.estrategia = estrategia;
    }
    //FIN GETTER AND SETTER

    public Jugador() {
    }

    public Jugador(String nombre, String tipo, boolean dealer, Jugador sigJugador) {
        IEstrategia Estr = new Humano();

        if (tipo.equalsIgnoreCase("Facil")) {
            Estr = new MaquinaFacil();
        } else if (tipo.equalsIgnoreCase("Intermedio")) {
            Estr = new MaquinaInter();
        } else if (tipo.equalsIgnoreCase("Dificil")) {
            Estr = new MaquinaDificil();
        }
        this.nombre = nombre;
        this.montoDisponible = 100;
        this.sigJugador = sigJugador;
        this.lstCartas = null;
        this.dealer = dealer;
        this.activo = true;
        this.uApuesta = 0;
        this.estrategia = Estr;
    }

    public Jugador(String nombre, Integer montoDisponible, Jugador sigJugador, List<Carta> lstCartas, boolean dealer, boolean activo, Integer uApuesta, IEstrategia estrategia) {
        this.nombre = nombre;
        this.montoDisponible = montoDisponible;
        this.sigJugador = sigJugador;
        this.lstCartas = lstCartas;
        this.dealer = dealer;
        this.activo = activo;
        this.uApuesta = uApuesta;
        this.estrategia = estrategia;
    }
    //IDENTIFICAR MANO

    public Integer[] identificarMano(List<Carta> lstCartasMesa) {
        List<Carta> cartas = new ArrayList();
        cartas.addAll(lstCartasMesa);
        cartas.addAll(lstCartas);
        Integer[] arrayCartas = pasarArray(cartas);
        ordenarCartas(arrayCartas);

        Integer[] res = new Integer[2];//El primer valor indica la jugada 1-POKER 2-PIERNA 3-PAR 4-CARTA ALTA  0-S/JUGADA y el segundo el valor de la carta
        res[0] = 0;
        res[1] = 0;
        try {
            if (esPoker(arrayCartas)[0] == 1) {
                res[0] = 1;
                res[1] = esPoker(arrayCartas)[1];
            } else if (esPierna(arrayCartas)[0] == 1) {
                res[0] = 2;
                res[1] = esPierna(arrayCartas)[1];
            } else if (esPar(arrayCartas)[0] == 1) {
                res[0] = 3;
                res[1] = esPar(arrayCartas)[1];
            } else {
                res[0] = 4;
                res[1] = arrayCartas[arrayCartas.length - 1].intValue();//es el último porque ya lo paso ordenado
            }
            return res;
        } catch (Exception e) {
            return res;
        }
    }

    public Integer[] esPoker(Integer cartas[])//Recibe el array de cartas ordenado de menor a mayor
    {
        Integer res[] = {0, 0};
        if (cartas.length != 0) {
            for (int i = cartas.length - 1; i >= 0; i--) {
                if (cuantasIguales(cartas, cartas[i]) == 4) {
                    res[0] = 1;//HAY POKER
                    res[1] = cartas[i];//PASO CARTA
                    i = -1;//CORTO EL FOR
                }
            }
        }
        return res;
    }

    public Integer[] esPierna(Integer cartas[])//Recibe el array de cartas ordenado de menor a mayor
    {
        Integer res[] = {0, 0};
        if (cartas.length != 0) {
            for (int i = cartas.length - 1; i >= 0; i--) {
                if (cuantasIguales(cartas, cartas[i]) == 3) {
                    res[0] = 1;//HAY PIERNA
                    res[1] = cartas[i];//PASO CARTA
                    i = -1;//CORTO EL FOR
                }
            }
        }
        return res;
    }

    public Integer[] esPar(Integer cartas[])//Recibe el array de cartas ordenado de menor a mayor
    {
        Integer res[] = {0, 0};
        if (cartas.length != 0) {
            for (int i = cartas.length - 1; i >= 0; i--) {
                if (cuantasIguales(cartas, cartas[i]) == 2) {
                    res[0] = 1;//HAY PAR
                    res[1] = cartas[i];//PASO CARTA
                    i = -1;//CORTO EL FOR
                }
            }
        }
        return res;
    }

    public Integer cuantasIguales(Integer cartas[], Integer num)//Devuelve un array de dos número, indican la cantidad de veces que está el mismo numero en la lista.
    {
        Integer cant = 0;
        for (int i = 0; i < cartas.length; i++) {
            if (cartas[i] == num) {
                cant++;
            }
        }

        return cant;
    }

    public Integer[] pasarArray(List<Carta> cartas) {
        Integer[] res = new Integer[cartas.size()];
        if (!cartas.isEmpty()) {
            for (int i = 0; i < cartas.size(); i++) {
                res[i] = cartas.get(i).getNumero();
            }
        }
        return res;
    }

    public void ordenarCartas(Integer cartas[]) {
        if (cartas.length != 0) {
            //Revisar esta funcion que mepa q no anda bien , aca salta exepcion
            Integer aux;
            for (int i = 0; i < cartas.length; i++) {
                for (int j = 0; j < i; j++) {
                    if ((cartas[i] < cartas[j] || cartas[j] == 1) && cartas[i] != 1)//Considera el as como el mayor de las cartas
                    {
                        aux = cartas[j];
                        cartas[j] = cartas[i];
                        cartas[i] = aux;
                    }
                }
            }
        }
    }
    //APUESTAS

    public void apostarCiega(int monto) {
        this.setuApuesta(monto);//asigna ultima apueta a jugador
        this.setMontoDisponible(montoDisponible - monto);//retira el dinero del jugador

    }

    public boolean apostar(int monto)//devuelve verdadero si le alcanza el monto al jugador y realiza la apuesta
    {
        boolean res = false;

        if ((montoDisponible - monto) >= 0) {
            this.setMontoDisponible(montoDisponible - monto);
            this.setuApuesta(monto);

            res = true;
        }
        return res;
    }
    //ESTRATEGIA

    public String apuesta(Integer[] puntajeApuesta) {
        return estrategia.apuesta(puntajeApuesta);
    }

    public boolean esHumano() {
        return estrategia.esHumano();
    }

    public int cuantoApostar(int monto, int uApuesta) {
        return estrategia.cuantoApostar(monto, uApuesta);
    }

    public void prestamoFichas() {
        if (prestamoActivo == false) {
            this.montoDisponible = this.montoDisponible + 100;
            prestamoActivo = true;
        }
    }
}
